home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE08 / MODEL / NODES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-01-06  |  6.7 KB  |  263 lines

  1. {*******************************************************
  2.                 TNodes [Nodes unit]
  3.  
  4. This unit contains the code for the TNode base class, the
  5. TBooleanNode and the TEndNode.
  6.  
  7. A TBooleanNode accepts input at run-time and compares it to
  8. the Criteria property. If the boolean result is yes the input
  9. is passed to the node connected to the YesPipe property and
  10. if no the input is passed to NoPipe. Finally, the Run method
  11. for either YesPipe or NoPipe is called.
  12.  
  13. A TEndNode is designed to connect at the end of each possible
  14. path that a given input could take. TEndNode implements an
  15. AfterRun event which allows a simple way of indicating where
  16. the input ended. There is also a ResultStr property which,
  17. along with the AfterRun method provides a mechanism for
  18. reporting results.
  19.  
  20. This scheme allows the developer to create a decision tree of any
  21. size and structure at design time. At run-time all you need do is
  22. provide input to BooleanNode1 and call its Run method. Each
  23. TEndNode in your structure would have its AfterRun event connected
  24. to a method which could perform any action desired. Most commonly
  25. this would be a method to display the ResultStr of the TEndNode
  26. which actually called the method. The code would look like this.
  27.  
  28. procedure TForm1.EndNode1AfterRun(Sender: TObject);
  29. begin
  30.   Label1.Caption := (Sender as TEndNode).ResultStr;
  31. end;
  32.  
  33. I hope you find this code useful. If you make improvements please
  34. e-mail me a copy. Enjoy.
  35.  
  36.                 Paul Warren
  37.        HomeGrown Software Development
  38.      (c) 1995 Langley British Columbia.
  39.               (604) 530-9097
  40.        e-mail:  hg_soft@uniserve.com
  41.   Home page: http://haven.uniserve.com/~hg_soft
  42.  
  43. ********************************************************}
  44.  
  45. unit Nodes;
  46.  
  47. interface
  48.  
  49. uses
  50.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  51.   Forms, Dialogs, EnhEdits, StrLib;
  52.  
  53. type
  54.   TNode = class(TComponent)
  55.   private
  56.     Input: real;
  57.     FInputAsReal: real;
  58.     FYesPipe: TNode;
  59.     FNoPipe: TNode;
  60.     procedure SetInputAsReal(NewValue: real);
  61.     function GetInputAsReal: real;
  62.     procedure Run; virtual; abstract;
  63.   public
  64.     { Public declarations }
  65.     property InputAsReal: real read GetInputAsReal write SetInputAsReal;
  66.     {property Input: TRealStr read FInput write FInput;}
  67.   published
  68.     { Published declarations }
  69.   end;
  70.  
  71.   TOperator = (opEquals, opGreaterThan, opGreaterOrEqual, opLessThan, opLessOrEqual);
  72.  
  73.   TBooleanNode = class(TNode)
  74.   private
  75.     { Private declarations }
  76.     FCritAsReal: real;
  77.     FEnabled: Boolean;
  78.     FCriteria: TRealStr;
  79.     FOperator: TOperator;
  80.     procedure SetCritAsReal(NewValue: real);
  81.     function GetCritAsReal: real;
  82.   protected
  83.     { Protected declarations }
  84.   public
  85.     { Public declarations }
  86.     constructor Create(AOwner: TComponent); override;
  87.     procedure Run; override;
  88.     property CritAsReal: real read GetCritAsReal write SetCritAsReal;
  89.   published
  90.     { Published declarations }
  91.     property Enabled: Boolean read FEnabled write FEnabled default True;
  92.     property Criteria: TRealStr read FCriteria write FCriteria;
  93.     property Operator: TOperator read FOperator write FOperator;
  94.     property YesPipe: TNode read FYesPipe write FYesPipe;
  95.     property NoPipe: TNode read FNoPipe write FNoPipe;
  96.   end;
  97.  
  98.   TEndNode = class(TNode)
  99.   private
  100.     { Private declarations }
  101.     FIsResult: boolean;
  102.     FResultStr: string;
  103.     FAfterRun: TNotifyEvent;
  104.     procedure SetAfterRun(Value: TNotifyEvent);
  105.   protected
  106.     { Protected declarations }
  107.     procedure After; dynamic;
  108.   public
  109.     { Public declarations }
  110.     constructor Create(AOwner: TComponent); override;
  111.     procedure Run; override;
  112.   published
  113.     { Published declarations }
  114.     property IsResult: Boolean read FIsResult write FIsResult default false;
  115.     property ResultStr: string read FResultStr write FResultStr;
  116.     property AfterRun: TNotifyEvent read FAfterRun write SetAfterRun;
  117.   end;
  118.  
  119. procedure Register;
  120.  
  121. implementation
  122.  
  123. { Methods to Get and Set the Input property
  124.   as a real type }
  125. function TNode.GetInputAsReal: real;
  126. var
  127.   code: integer;
  128. begin
  129.   try
  130.     Result := Input;
  131.   except
  132.   end;
  133. end;
  134.  
  135. procedure TNode.SetInputAsReal(NewValue: real);
  136. begin
  137.   try
  138.     Input := NewValue;
  139.   except
  140.   end;
  141. end;
  142.  
  143. { construct TBooleanNode }
  144. constructor TBooleanNode.Create(AOwner: TComponent);
  145. begin
  146.   inherited Create(AOwner);
  147.   FEnabled := true;
  148.   FYesPipe := nil;
  149.   FNoPipe := nil;
  150. end;
  151.  
  152. { Methods to Get and Set the Criteria property
  153.   as a real type }
  154. function TBooleanNode.GetCritAsReal: real;
  155. var
  156.   code: integer;
  157. begin
  158.   try
  159.     Result := StrToReal(code, Criteria);
  160.   except
  161.   end;
  162. end;
  163.  
  164. procedure TBooleanNode.SetCritAsReal(NewValue: real);
  165. begin
  166.   try
  167.     Criteria := RealToStr(NewValue, 2);
  168.   except
  169.   end;
  170. end;
  171.  
  172. { Run method. Compares Input to criteria and passes
  173.   Input to YesPipe or NoPipe. Calls Run for YesPipe
  174.   or NoPipe }
  175. procedure TBooleanNode.Run;
  176. begin
  177.   case operator of
  178.     opEquals: if InputAsReal = CritAsReal then
  179.     begin
  180.       YesPipe.InputAsReal := Input;
  181.       YesPipe.Run;
  182.     end else
  183.     begin
  184.       NoPipe.InputAsReal := Input;
  185.       NoPipe.Run;
  186.     end;
  187.     opGreaterThan: if InputAsReal > CritAsReal then
  188.     begin
  189.       YesPipe.InputAsReal := Input;
  190.       YesPipe.Run;
  191.     end else
  192.     begin
  193.       NoPipe.InputAsReal := Input;
  194.       NoPipe.Run;
  195.     end;
  196.     opGreaterOrEqual: if InputAsReal >= CritAsReal then
  197.     begin
  198.       YesPipe.InputAsReal := Input;
  199.       YesPipe.Run;
  200.     end else
  201.     begin
  202.       NoPipe.InputAsReal := Input;
  203.       NoPipe.Run;
  204.     end;
  205.     opLessThan: if InputAsReal < CritAsReal then
  206.     begin
  207.       YesPipe.InputAsReal := Input;
  208.       YesPipe.Run;
  209.     end else
  210.     begin
  211.       NoPipe.InputAsReal := Input;
  212.       NoPipe.Run;
  213.     end;
  214.     opLessOrEqual: if InputAsReal <= CritAsReal then
  215.     begin
  216.       YesPipe.InputAsReal := Input;
  217.       YesPipe.Run;
  218.     end else
  219.     begin
  220.       NoPipe.InputAsReal := Input;
  221.       NoPipe.Run;
  222.     end;
  223.   end;
  224. end;
  225.  
  226. { construct TEndNode }
  227. constructor TEndNode.Create(AOwner: TComponent);
  228. begin
  229.   inherited Create(AOwner);
  230.   FIsResult := false;
  231. end;
  232.  
  233. { Set AfterRun event }
  234. procedure TEndNode.SetAfterRun(Value: TNotifyEvent);
  235. begin
  236.   FAfterRun := Value;
  237. end;
  238.  
  239. { implement AfterRun event }
  240. procedure TEndNode.After;
  241. begin
  242.   if Assigned(FAfterRun) then FAfterRun(Self);
  243.   FIsResult := false;
  244. end;
  245.  
  246. { Run method. Just causes AfterRun event to be Run.
  247.   IsResult is there for polling TEndNodes for the
  248.   result. Not very useful }
  249. procedure TEndNode.Run;
  250. begin
  251.   FIsResult := true;
  252.   After;
  253. end;
  254.  
  255. { Register components }
  256. procedure Register;
  257. begin
  258.   RegisterComponents('Misc', [TBooleanNode]);
  259.   RegisterComponents('Misc', [TEndNode]);
  260. end;
  261.  
  262. end.
  263.